#include <iostream>
using namespace std;

/*
    实现多态--》虚函数实现

    语法规则：
          virtual  返回值  函数名(参数)
          {

          }

    虚函数是如何实现多态的  --》 虚函数底层原理
    1.一个类定义了虚函数，这个类地址空间会多出一个指针
    2.该指针用来指向虚函数表的首地址的
       虚函数表：用来存放当前这个类所有的虚函数首地址的一种数据结构
    3.父类定义成虚函数，自动的同名eat默认也是虚函数，子类的eat前面virtual可以省略
*/

class Animal
{
public:
    virtual void eat()
    {
        cout << "animal eat" << endl;
    }
};

class Dog : public Animal
{
public:
    void eat()
    {
        cout << "dog eat" << endl;
    }
};

class Cat : public Animal
{
public:
    void eat()
    {
        cout << "cat eat" << endl;
    }
};

class Sheep : public Animal
{
public:
    void eat()
    {
        cout << "sheep eat" << endl;
    }
};

class Pig : public Animal
{
public:
    void eat()
    {
        cout << "pig eat" << endl;
    }
};

// 封装函数，展示各种动物吃东西的行为
void showAnimalEat(Animal &animal)
{
    animal.eat();
}

// void showAnimalEat(Animal *animal)
// {
//     animal->eat();
// }

// void showAnimalEat(Animal animal) // 只有引用和指针的形参才具有多态性
// {
//     animal.eat();
// }

int main()
{
    Animal animal;
    Dog dog;
    Cat cat;
    Sheep sheep;
    Pig pig;

    showAnimalEat(animal);
    showAnimalEat(dog);
    showAnimalEat(cat);
    showAnimalEat(sheep);
    showAnimalEat(pig);

    // showAnimalEat(&animal);
    // showAnimalEat(&dog);
    // showAnimalEat(&cat);
    // showAnimalEat(&sheep);
    // showAnimalEat(&pig);

    return 0;
}
